package com.gan.yidademo.common.util;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.gan.yidademo.common.constant.HaiKangConstant;
import com.gan.yidademo.haikang.model.dto.person.PersonInfoDto;
import com.gan.yidademo.haikang.model.request.permission.PermissionRequest;
import com.gan.yidademo.haikang.model.request.permission.PersonData;
import com.gan.yidademo.haikang.model.request.person.PersonInfoRequest;
import com.gan.yidademo.haikang.model.request.event.EventsRequest;
import com.gan.yidademo.haikang.model.request.person.SelectPersonInfoRequest;
import com.gan.yidademo.haikang.model.request.resource.GetIndexCodesRequest;
import com.gan.yidademo.haikang.model.request.resource.ResourceInfo;
import com.hikvision.artemis.sdk.ArtemisHttpUtil;
import com.hikvision.artemis.sdk.config.ArtemisConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.stereotype.Service;

import java.rmi.MarshalledObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author gbw
 * @date 2023/10/09
 * 海康威视工具类
 */
@Service
@Slf4j
public class HaiKangUtil {
    /**
     * 基本路径前缀
     */
    private static final String BASE_URL = "/artemis";
    /**
     * 订阅事件【如抓拍事件】
     */
    private static final String subscribeToEventsApi = BASE_URL + "/api/eventService/v1/eventSubscriptionByEventTypes";
    /**
     * 查询设备列表
     */
    private static final String getEquipmentInfoApi = BASE_URL + "/api/irds/v2/resource/resourcesByParams";
    /**
     * 新增人员&人脸信息
     */
    private static final String addPersonInfoApi = BASE_URL + "/api/resource/v2/person/single/add";
    /**
     * 删除人员&人脸信息
     */
    private static final String deletePersonInfoApi = BASE_URL + "/api/pmas/v1/person/batch/delete";
    /**
     * 获取人员列表
     */
    private static final String getPersonInfoApi = BASE_URL + "/api/resource/v2/person/personList";
    /**
     * 根据条件[姓名，组织id，性别]查询获取人员列表
     */
    private static final String selectPersonInfoApi = BASE_URL + "/api/resource/v2/person/advance/personList";
    /**
     * 新增权限接口
     */
    private static final String addPermissionApi = BASE_URL + "/api/acps/v1/auth_config/add";
    /**
     * 查询门禁资源列表
     */
    private static final String getResourceIndexCodesApi = BASE_URL + "/api/irds/v2/resource/resourcesByParams";
    /**
     * 删除权限接口
     */
    private static final String deletePermissionApi = BASE_URL + "/api/acps/v1/auth_config/delete";
    /**
     * 取消订阅事件
     */
    private static final String unsubscribeToEventsApi = BASE_URL + "/api/eventService/v1/eventUnSubscriptionByEventTypes";
    /**
     * 新增人脸信息
     */
    private static final String addFaceInfoApi = BASE_URL + "/api/resource/v1/face/single/add";
    /**
     * 修改人脸信息
     */
    private static final String updateFaceInfoApi = BASE_URL + "/api/resource/v1/face/single/update";
    /**
     * 获取组织列表
     */
    private static final String getOrgListApi = BASE_URL + "/api/resource/v1/org/orgList";
    /**
     * 获取门禁设备列表
     */
    private static final String getAcsDeviceListApi = BASE_URL + "/api/resource/v2/acsDevice/search";


    /**
     * 接口调用配置&初始化
     */
    static ArtemisConfig artemisConfig;

    static {
        artemisConfig = new ArtemisConfig();
        // 平台（nginx）IP和端口
        artemisConfig.setHost("112.53.191.202:1443");
        // 合作方ak
        artemisConfig.setAppKey("25623073");
        // 合作方sk
        artemisConfig.setAppSecret("vp1mVfV06rl65V0pUcCV");
    }


    /**
     * 订阅事件
     *
     * @return
     */
    public static boolean subscribeToEvents(EventsRequest eventsRequest) {
        // 创建接口路径
        Map<String, String> path = new HashMap<String, String>(1) {
            {
                put("https://", subscribeToEventsApi);
            }
        };
        String body = JSONUtil.toJsonStr(eventsRequest);
        // 调用接口
        String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, "application/json");
        // 处理&返回结果
        JSONObject jsonResult = new JSONObject(result);
        String code = (String) jsonResult.get("code");
        if (!HaiKangConstant.STATUS_CODE.SUCCESS.equals(code)) {
            throw new RuntimeException("订阅事件失败！:" + jsonResult.get("msg"));
        }
        return true;
    }

    /**
     * 取消订阅事件
     *
     * @return
     */
    public static boolean unsubscribeToEvents(EventsRequest eventsRequest) {
        // 创建接口路径
        Map<String, String> path = new HashMap<String, String>(1) {
            {
                put("https://", unsubscribeToEventsApi);
            }
        };
        String body = JSONUtil.toJsonStr(eventsRequest);
        // 调用接口
        String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, "application/json");
        // 处理&返回结果
        JSONObject jsonResult = new JSONObject(result);
        String code = (String) jsonResult.get("code");
        if (!HaiKangConstant.STATUS_CODE.SUCCESS.equals(code)) {
            throw new RuntimeException("取消订阅事件失败！:" + jsonResult.get("msg"));
        }
        return true;
    }

    /**
     * 新增人员信息
     *
     * @return
     */
    public static Map addPersonInfoOnly(PersonInfoRequest personInfoRequest) {
        // 创建接口路径
        Map<String, String> path = new HashMap<String, String>(1) {
            {
                put("https://", addPersonInfoApi);
            }
        };
        String body = JSONUtil.toJsonStr(personInfoRequest);
        // 调用接口
        String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, "application/json");
        // 处理&返回结果
        JSONObject jsonResult = new JSONObject(result);
        String code = jsonResult.getStr("code");
        if (!HaiKangConstant.STATUS_CODE.SUCCESS.equals(code)) {
            throw new RuntimeException("新增人员信息失败！:" + jsonResult.get("msg"));
        }
        // 新增成功时自动下发权限到门禁点上
        JSONObject data = jsonResult.getJSONObject("data");
        HashMap<String, String> res = JSONUtil.toBean(data, HashMap.class);
        return res;
    }


    /**
     * 新增人员信息&下发权限
     *
     * @return
     */
    public static Map addPersonInfoWithAuth(PersonInfoRequest personInfoRequest) {
        // 创建接口路径
        Map<String, String> path = new HashMap<String, String>(1) {
            {
                put("https://", addPersonInfoApi);
            }
        };
        String body = JSONUtil.toJsonStr(personInfoRequest);
        // 调用接口
        String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, "application/json");
        // 处理&返回结果
        JSONObject jsonResult = new JSONObject(result);
        String code = jsonResult.getStr("code");
        if (!HaiKangConstant.STATUS_CODE.SUCCESS.equals(code)) {
            throw new RuntimeException("新增人员信息失败！:" + jsonResult.get("msg"));
        }
        // 新增成功时自动下发权限到门禁点上
        JSONObject data = jsonResult.getJSONObject("data");
        String personId = data.getStr("personId");
        List<String> indexCodes = new ArrayList<>();
        indexCodes.add(personId);
        PersonData personData = PersonData.builder().personDataType("person").indexCodes(indexCodes).build();
        List<PersonData> personDatas = new ArrayList<>();
        personDatas.add(personData);
        // 获得所有门禁列表信息
        GetIndexCodesRequest getIndexCodesRequest = GetIndexCodesRequest.builder()
                .pageSize(100)
                .pageNo(1)
                .resourceType("door")
                .build();
        List<ResourceInfo> resourceInfos = HaiKangUtil.getResourceIndexCodes(getIndexCodesRequest);
        PermissionRequest permissionRequest = PermissionRequest.builder()
                .resourceInfos(resourceInfos)
                .personDatas(personDatas)
                .build();
        boolean flag = HaiKangUtil.addPermission(permissionRequest);
        if (flag) {
            log.info("下发权限成功!");
        }
        HashMap<String, String> res = JSONUtil.toBean(data, HashMap.class);
        return res;
    }


    /**
     * 删除人员信息&删除权限
     *
     * @param personIds 人员Id列表可以通过获取人员列表接口获得
     * @return
     */
    public static boolean deletePersonInfoWithAuth(List<String> personIds) {
        // 创建接口路径
        Map<String, String> path = new HashMap<String, String>(1) {
            {
                put("https://", deletePersonInfoApi);
            }
        };
        Map<String, List<String>> bodyMap = new HashMap<String, List<String>>(1) {{
            put("personIndexCodes", personIds);
        }};
        Map<String, String> head = new HashMap<String, String>(1) {{
            put("userId", "admin");
        }};
        String body = JSONUtil.toJsonStr(bodyMap);
        // 调用接口
        String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, "application/json", head);
        // 处理&返回结果
        JSONObject jsonResult = new JSONObject(result);
        String code = jsonResult.getStr("code");
        if (!HaiKangConstant.STATUS_CODE.SUCCESS.equals(code)) {
            throw new RuntimeException("删除人员信息失败！:" + jsonResult.get("msg"));
        }
        // 删除成功时自动删除门禁点上的权限
        PersonData personData = PersonData.builder().personDataType("person").indexCodes(personIds).build();
        List<PersonData> personDatas = new ArrayList<>();
        personDatas.add(personData);
        // 获得所有门禁列表信息
        GetIndexCodesRequest getIndexCodesRequest = GetIndexCodesRequest.builder()
                .pageSize(100)
                .pageNo(1)
                .resourceType("door")
                .build();
        List<ResourceInfo> resourceInfos = HaiKangUtil.getResourceIndexCodes(getIndexCodesRequest);
        PermissionRequest permissionRequest = PermissionRequest.builder()
                .resourceInfos(resourceInfos)
                .personDatas(personDatas)
                .build();
        boolean flag = HaiKangUtil.deletePermission(permissionRequest);
        if (flag) {
            log.info("删除权限成功!");
        }
        return true;
    }

    /**
     * 修改人脸信息
     *
     * @return
     */
    public static boolean updateFaceByPersonId(String personId, String faceId, String faceData) {
        // 创建接口路径
        Map<String, String> path = new HashMap<String, String>(1) {
            {
                put("https://", updateFaceInfoApi);
            }
        };
        HashMap<String, String> hashMap = new HashMap<String, String>() {{
            put("faceId", faceId);
            put("faceData", faceData);
        }};
        String body = JSONUtil.toJsonStr(hashMap);
        // 调用接口
        String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, "application/json");
        // 处理&返回结果
        JSONObject jsonResult = new JSONObject(result);
        String code = (String) jsonResult.get("code");
        if (!HaiKangConstant.STATUS_CODE.SUCCESS.equals(code)) {
            throw new RuntimeException("修改人脸信息失败！:" + jsonResult.get("msg"));
        }
        // 重新设置权限
        HaiKangUtil.resetPermByPersonId(personId);
        log.info("修改人脸信息成功！");
        return true;
    }


    /**
     * 查询人员信息,返回personId列表
     *
     * @return
     */
    public static List<String> getPersonInfo() {
        // 创建接口路径
        Map<String, String> path = new HashMap<String, String>(1) {
            {
                put("https://", getPersonInfoApi);
            }
        };
        HashMap<String, Integer> hashMap = new HashMap<String, Integer>() {{
            put("pageNo", 1);
            put("pageSize", 200);
        }};
        String body = JSONUtil.toJsonStr(hashMap);
        // 调用接口
        String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, "application/json");
        // 处理&返回结果
        JSONObject jsonResult = new JSONObject(result);
        String code = (String) jsonResult.get("code");
        if (!HaiKangConstant.STATUS_CODE.SUCCESS.equals(code)) {
            throw new RuntimeException("新增人员信息失败！:" + jsonResult.get("msg"));
        }
        JSONObject data = (JSONObject) jsonResult.get("data");
        JSONArray personInfoList = (JSONArray) data.get("list");
        List<String> personIds = new ArrayList<>();
        for (Object o : personInfoList) {
            JSONObject person = JSONUtil.parseObj(o);
            personIds.add(person.get("personId").toString());
        }
        return personIds;
    }


    /**
     * 根据条件查询获取人员相信信息列表
     *
     * @return
     */
    public static List<PersonInfoDto> selectPersonInfo(SelectPersonInfoRequest selectPersonInfoRequest) {
        // 创建接口路径
        Map<String, String> path = new HashMap<String, String>(1) {
            {
                put("https://", selectPersonInfoApi);
            }
        };
        String body = JSONUtil.toJsonStr(selectPersonInfoRequest);
        // 调用接口
        String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, "application/json");
        // 处理&返回结果
        JSONObject jsonResult = new JSONObject(result);
        String code = (String) jsonResult.get("code");
        if (!HaiKangConstant.STATUS_CODE.SUCCESS.equals(code)) {
            throw new RuntimeException("查询人员信息失败！:" + jsonResult.get("msg"));
        }
        JSONObject data = (JSONObject) jsonResult.get("data");
        List<PersonInfoDto> personInfos = data.getBeanList("list", PersonInfoDto.class);
        return personInfos;
    }


    /**
     * 查询门禁资源列表返回设备的设备列表
     *
     * @return
     */
    public static List<ResourceInfo> getResourceIndexCodes(GetIndexCodesRequest getIndexCodesRequest) {
        // 创建接口路径
        Map<String, String> path = new HashMap<String, String>(1) {
            {
                put("https://", getResourceIndexCodesApi);
            }
        };
        String body = JSONUtil.toJsonStr(getIndexCodesRequest);
        // 调用接口
        String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, "application/json");
        // 处理&返回结果
        JSONObject jsonResult = new JSONObject(result);
        String code = (String) jsonResult.get("code");
        if (!HaiKangConstant.STATUS_CODE.SUCCESS.equals(code)) {
            throw new RuntimeException("新增权限失败！:" + jsonResult.get("msg"));
        }
        JSONObject data = (JSONObject) jsonResult.get("data");
        List<ResourceInfo> res = new ArrayList<>();
        JSONArray list = (JSONArray) data.get("list");
        for (Object item : list) {
            ResourceInfo resourceInfo = new ResourceInfo();
            JSONObject doorInfo = (JSONObject) item;
            resourceInfo.setResourceType("door");
            resourceInfo.setResourceIndexCode(doorInfo.getStr("indexCode"));
            Integer channelNo = doorInfo.getInt("channelNo");
            ArrayList<Integer> channelNos = new ArrayList<>();
            channelNos.add(channelNo);
            resourceInfo.setChannelNos(channelNos);
            res.add(resourceInfo);
        }
        return res;
    }


    /**
     * 新增权限
     *
     * @return
     */
    public static boolean addPermission(PermissionRequest permissionRequest) {
        // 创建接口路径
        Map<String, String> path = new HashMap<String, String>(1) {
            {
                put("https://", addPermissionApi);
            }
        };
        Map<String, String> head = new HashMap<String, String>(2) {  //post请求的header参数
            {
                put("tagId", "frs");
            }
        };
        String body = JSONUtil.toJsonStr(permissionRequest);
        // 调用接口
        String result = ArtemisHttpUtil
                .doPostStringArtemis(path, body, null, null, "application/json", head);

        // 处理&返回结果
        JSONObject jsonResult = new JSONObject(result);
        String code = (String) jsonResult.get("code");
        if (!HaiKangConstant.STATUS_CODE.SUCCESS.equals(code)) {
            throw new RuntimeException("新增权限失败！:" + jsonResult.get("msg"));
        }
        return true;
    }

    /**
     * 删除权限
     *
     * @return
     */
    public static boolean deletePermission(PermissionRequest permissionRequest) {
        // 创建接口路径
        Map<String, String> path = new HashMap<String, String>(1) {
            {
                put("https://", deletePermissionApi);
            }
        };
        Map<String, String> head = new HashMap<String, String>(2) {  //post请求的header参数
            {
                put("tagId", "frs");
            }
        };
        String body = JSONUtil.toJsonStr(permissionRequest);
        // 调用接口
        String result = ArtemisHttpUtil
                .doPostStringArtemis(path, body, null, null, "application/json", head);

        // 处理&返回结果
        JSONObject jsonResult = new JSONObject(result);
        String code = (String) jsonResult.get("code");
        if (!HaiKangConstant.STATUS_CODE.SUCCESS.equals(code)) {
            throw new RuntimeException("删除权限失败！:" + jsonResult.get("msg"));
        }
        return true;
    }

    /**
     * 修改权限-先删除原有的再插入一条新的记录
     *
     * @return
     */
    public static boolean updatePermission(PermissionRequest permissionRequest) {
        // 先删除后新增
        boolean flag = deletePermission(permissionRequest) && addPermission(permissionRequest);
        return flag;
    }

    /**
     * 重置所有权限【将所有权限删除掉，再一次性从人员信息中同步所有人员信息】
     *
     * @return
     */
    public static boolean resetPermission() {
        // 获得所有门禁列表信息
        GetIndexCodesRequest getIndexCodesRequest = GetIndexCodesRequest.builder()
                .pageSize(100)
                .pageNo(1)
                .resourceType("door")
                .build();
        List<ResourceInfo> resourceInfos = HaiKangUtil.getResourceIndexCodes(getIndexCodesRequest);

        PermissionRequest permissionRequest = PermissionRequest.builder().resourceInfos(resourceInfos).build();
        boolean delFlag = HaiKangUtil.deletePermission(permissionRequest);
        boolean addFlag = false;
        // 得到所有人员信息
        List<String> indexCodes = HaiKangUtil.getPersonInfo();
        PersonData personData = PersonData.builder().personDataType("person").indexCodes(indexCodes).build();
        List<PersonData> personDatas = new ArrayList<>();
        personDatas.add(personData);
        permissionRequest.setPersonDatas(personDatas);
        if (delFlag) {
            addFlag = HaiKangUtil.addPermission(permissionRequest);
        }
        return addFlag;
    }

    /**
     * 根据personId重置权限
     *
     * @return
     */
    public static boolean resetPermByPersonId(String personId) {
        // 获得所有门禁列表信息
        GetIndexCodesRequest getIndexCodesRequest = GetIndexCodesRequest.builder()
                .pageSize(100)
                .pageNo(1)
                .resourceType("door")
                .build();
        List<ResourceInfo> resourceInfos = HaiKangUtil.getResourceIndexCodes(getIndexCodesRequest);

        PermissionRequest permissionRequest = PermissionRequest.builder().resourceInfos(resourceInfos).build();
        boolean delFlag = HaiKangUtil.deletePermission(permissionRequest);
        boolean addFlag = false;
        // 设置人员信息
        List<String> indexCodes = new ArrayList<>(1);
        indexCodes.add(personId);
        PersonData personData = PersonData.builder().personDataType("person").indexCodes(indexCodes).build();
        List<PersonData> personDatas = new ArrayList<>();
        personDatas.add(personData);
        permissionRequest.setPersonDatas(personDatas);
        if (delFlag) {
            log.info("删除权限成功");
            addFlag = HaiKangUtil.addPermission(permissionRequest);
            log.info("新增权限成功");
        }
        return addFlag;
    }

    /**
     * 返回组织列表
     *
     * @return
     */
    public static JSONArray getOrgList() {
        // 创建接口路径
        Map<String, String> path = new HashMap<String, String>(1) {
            {
                put("https://", getOrgListApi);
            }
        };
        HashMap<String, Integer> hashMap = new HashMap<String, Integer>() {{
            put("pageNo", 1);
            put("pageSize", 5);
        }};
        String body = JSONUtil.toJsonStr(hashMap);
        // 调用接口
        String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, "application/json");
        // 处理&返回结果
        JSONObject jsonResult = new JSONObject(result);
        String code = (String) jsonResult.get("code");
        if (!HaiKangConstant.STATUS_CODE.SUCCESS.equals(code)) {
            throw new RuntimeException("新增人员信息失败！:" + jsonResult.get("msg"));
        }
        JSONObject data = (JSONObject) jsonResult.get("data");
        JSONArray personInfoList = (JSONArray) data.get("list");
        return personInfoList;
    }

    /**
     * 返回门禁设备列表
     *
     * @return
     */
    public static JSONArray getAcsDeviceList() {
        // 创建接口路径
        Map<String, String> path = new HashMap<String, String>(1) {
            {
                put("https://", getAcsDeviceListApi);
            }
        };
        HashMap<String, Integer> hashMap = new HashMap<String, Integer>() {{
            put("pageNo", 1);
            put("pageSize", 5);
        }};
        String body = JSONUtil.toJsonStr(hashMap);
        // 调用接口
        String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, "application/json");
        // 处理&返回结果
        JSONObject jsonResult = new JSONObject(result);
        String code = (String) jsonResult.get("code");
        if (!HaiKangConstant.STATUS_CODE.SUCCESS.equals(code)) {
            throw new RuntimeException("新增人员信息失败！:" + jsonResult.get("msg"));
        }
        JSONObject data = (JSONObject) jsonResult.get("data");
        JSONArray personInfoList = (JSONArray) data.get("list");
        return personInfoList;
    }


}
